home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / comm / mail / Mutt089src.lha / Mutt-0.89i-AMIGA / src / lib.c < prev    next >
C/C++ Source or Header  |  1998-01-28  |  15KB  |  792 lines

  1. /*
  2.  * Copyright (C) 1996-8 Michael R. Elkins <me@cs.hmc.edu>
  3.  * 
  4.  *     This program is free software; you can redistribute it and/or modify
  5.  *     it under the terms of the GNU General Public License as published by
  6.  *     the Free Software Foundation; either version 2 of the License, or
  7.  *     (at your option) any later version.
  8.  * 
  9.  *     This program is distributed in the hope that it will be useful,
  10.  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  *     GNU General Public License for more details.
  13.  * 
  14.  *     You should have received a copy of the GNU General Public License
  15.  *     along with this program; if not, write to the Free Software
  16.  *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  */ 
  18.  
  19. #include "mutt.h"
  20. #include "mutt_regex.h"
  21. #include "mutt_curses.h"
  22. #include "mime.h"
  23.  
  24. #include <string.h>
  25. #include <ctype.h>
  26. #include <unistd.h>
  27. #include <stdlib.h>
  28. #include <sys/wait.h>
  29. #include <errno.h>
  30. #include <pwd.h>
  31. #include <sys/stat.h>
  32. #include <fcntl.h>
  33.  
  34. BODY *mutt_new_body (void)
  35. {
  36.   BODY *p = (BODY *) safe_calloc (1, sizeof (BODY));
  37.     
  38.   p->disposition = DISPATTACH;
  39.   p->use_disp = 1;
  40.   return (p);
  41. }
  42.  
  43. BODY* mutt_dup_body (BODY *b)
  44. {
  45.   BODY *bn;
  46.  
  47.   bn = mutt_new_body();
  48.   memcpy(bn, b, sizeof (BODY));
  49.   return bn;
  50. }
  51.  
  52. void mutt_free_body (BODY **p)
  53. {
  54.   BODY *a = *p, *b;
  55.  
  56.   while (a)
  57.   {
  58.     b = a;
  59.     a = a->next; 
  60.  
  61.     if (b->parameter)
  62.       mutt_free_parameter (&b->parameter);
  63.     if (b->unlink && b->filename)
  64.       unlink (b->filename);
  65.     safe_free ((void **) &b->filename);
  66.     safe_free ((void **) &b->content);
  67.     safe_free ((void **) &b->subtype);
  68.     safe_free ((void **) &b->description);
  69.     safe_free ((void **) &b->form_name);
  70.  
  71.     if (b->hdr)
  72.     {
  73.       /* Don't free twice (b->hdr->content = b->parts) */
  74.       b->hdr->content = NULL;
  75.       mutt_free_header(&b->hdr);
  76.     }
  77.  
  78.     if (b->parts)
  79.       mutt_free_body (&b->parts);
  80.  
  81.     safe_free ((void **) &b);
  82.   }
  83.  
  84.   *p = 0;
  85. }
  86.  
  87. void mutt_free_parameter (PARAMETER **p)
  88. {
  89.   PARAMETER *t = *p;
  90.   PARAMETER *o;
  91.  
  92.   while (t)
  93.   {
  94.     safe_free ((void **) &t->attribute);
  95.     safe_free ((void **) &t->value);
  96.     o = t;
  97.     t = t->next;
  98.     safe_free ((void **) &o);
  99.   }
  100.   *p = 0;
  101. }
  102.  
  103. void mutt_free_list (LIST **list)
  104. {
  105.   LIST *p;
  106.   
  107.   if (!list) return;
  108.   while (*list)
  109.   {
  110.     p = *list;
  111.     *list = (*list)->next;
  112.     safe_free ((void **) &p->data);
  113.     safe_free ((void **) &p);
  114.   }
  115. }
  116.  
  117. HEADER *mutt_dup_header(HEADER *h)
  118. {
  119.   HEADER *hnew;
  120.  
  121.   hnew = mutt_new_header();
  122.   memcpy(hnew, h, sizeof (HEADER));
  123.   return hnew;
  124. }
  125.  
  126. void mutt_free_header (HEADER **h)
  127. {
  128.   mutt_free_envelope (&(*h)->env);
  129.   mutt_free_body (&(*h)->content);
  130.   safe_free ((void **) &(*h)->tree);
  131.   safe_free ((void **) &(*h)->path);
  132.   safe_free ((void **) h);
  133. }
  134.  
  135. /* returns true if the header contained in "s" is in list "t" */
  136. int mutt_matches_ignore (const char *s, LIST *t)
  137. {
  138.   for (; t; t = t->next)
  139.   {
  140.     if (!strncasecmp (s, t->data, strlen (t->data)) || *t->data == '*')
  141.       return 1;
  142.   }
  143.   return 0;
  144. }
  145.  
  146. /* prepend the path part of *path to *link */
  147. void mutt_expand_link (char *newpath, const char *path, const char *link)
  148. {
  149.   const char *lb = NULL;
  150.   size_t len;
  151.  
  152.   /* link is full path */
  153.   if (*link == '/')
  154.   {
  155.     strfcpy (newpath, link, _POSIX_PATH_MAX);
  156.     return;
  157.   }
  158.  
  159.   if ((lb = strrchr (path, '/')) == NULL)
  160.   {
  161.     /* no path in link */
  162.     strfcpy (newpath, link, _POSIX_PATH_MAX);
  163.     return;
  164.   }
  165.  
  166.   len = lb - path + 1;
  167.   memcpy (newpath, path, len);
  168.   strfcpy (newpath + len, link, _POSIX_PATH_MAX - len);
  169. }
  170.  
  171. char *mutt_expand_path (char *s, size_t slen)
  172. {
  173.   char p[_POSIX_PATH_MAX] = "";
  174.   char *q = NULL;
  175.  
  176.   if (*s == '~')
  177.   {
  178.     if (*(s + 1) == '/' || *(s + 1) == 0)
  179.       snprintf (p, sizeof (p), "%s%s", Homedir, s + 1);
  180.     else
  181.     {
  182.       struct passwd *pw;
  183.  
  184.       q = strchr (s + 1, '/');
  185.       if (q)
  186.     *q = 0;
  187.       if ((pw = getpwnam (s + 1)))
  188.     snprintf (p, sizeof (p), "%s/%s", pw->pw_dir, q ? q + 1 : "");
  189.       else
  190.       {
  191.     /* user not found! */
  192.     if (q)
  193.       *q = '/';
  194.     return (NULL);
  195.       }
  196.     }
  197.   }
  198.   else if (*s == '=' || *s == '+')
  199.     snprintf (p, sizeof (p), "%s/%s", Maildir, s + 1);
  200.   else
  201.   {
  202.     if (*s == '>')
  203.       q = Inbox;
  204.     else if (*s == '<')
  205.       q = Outbox;
  206.     else if (*s == '!')
  207.       q = Spoolfile;
  208.     else if (*s == '-')
  209.       q = LastFolder;
  210.     else
  211.       return s;
  212.  
  213.     if (!*q)
  214.       return s;
  215.     snprintf (p, sizeof (p), "%s%s", q, s + 1);
  216.   }
  217.   if (*p)
  218.     strfcpy (s, p, slen); /* replace the string with the expanded version. */
  219.   return (s);
  220. }
  221.  
  222. /* returns TRUE if the given address belongs to the user. */
  223. int mutt_addr_is_user (ADDRESS *addr)
  224. {
  225.   char buf[LONG_STRING];
  226.  
  227.   /* NULL address is assumed to be the user. */
  228.   if (!addr)
  229.     return 1;
  230.  
  231.   if (!addr->mailbox)
  232.     return 0;
  233.  
  234.   if (strcasecmp (addr->mailbox, Username) == 0)
  235.   {
  236.     if (!addr->host || *addr->host == '@' ||
  237.     strcasecmp (addr->host, Hostname) == 0 ||
  238.     strcasecmp (addr->host, Fqdn) == 0)
  239.       return 1;
  240.   }
  241.  
  242.   if (Alternates.pattern)
  243.   {
  244.     buf[0] = 0;
  245.     mutt_simple_address (buf, sizeof (buf), addr);
  246.     if (regexec (Alternates.rx, buf, 0, NULL, 0) == 0)
  247.       return 1;
  248.   }
  249.   return 0;
  250. }
  251.  
  252. void *safe_calloc (size_t nmemb, size_t size)
  253. {
  254.   void *p;
  255.  
  256.   if (!nmemb || !size)
  257.     return NULL;
  258.   if (!(p = calloc (nmemb, size)))
  259.   {
  260.     mutt_error ("Out of memory");
  261.     sleep (1);
  262.     mutt_exit (1);
  263.   }
  264.   return p;
  265. }
  266.  
  267. void *safe_malloc (unsigned int siz)
  268. {
  269.   void *p;
  270.  
  271.   if (siz == 0)
  272.     return 0;
  273.   if ((p = (void *) malloc (siz)) == 0)
  274.   {
  275.     mutt_error ("Out of memory!");
  276.     sleep (1);
  277.     mutt_exit (1);
  278.   }
  279.   return (p);
  280. }
  281.  
  282. void safe_realloc (void **p, size_t siz)
  283. {
  284.   void *r;
  285.  
  286.   if (siz == 0)
  287.   {
  288.     if (*p)
  289.     {
  290.       free (*p);
  291.       *p = NULL;
  292.     }
  293.     return;
  294.   }
  295.  
  296.   if (*p)
  297.     r = (void *) realloc (*p, siz);
  298.   else
  299.   {
  300.     /* realloc(NULL, nbytes) doesn't seem to work under SunOS 4.1.x */
  301.     r = (void *) malloc (siz);
  302.   }
  303.  
  304.   if (!r)
  305.   {
  306.     mutt_error ("Out of memory!");
  307.     sleep (1);
  308.     mutt_exit (1);
  309.   }
  310.  
  311.   *p = r;
  312. }
  313.  
  314. void safe_free (void **p)
  315. {
  316.   if (*p)
  317.   {
  318.     free (*p);
  319.     *p = 0;
  320.   }
  321. }
  322.  
  323. char *safe_strdup (const char *s)
  324. {
  325.   char *p;
  326.   size_t l;
  327.  
  328.   if (!s || !*s) return 0;
  329.   l = strlen (s) + 1;
  330.   p = (char *)safe_malloc (l);
  331.   memcpy (p, s, l);
  332.   return (p);
  333. }
  334.  
  335. char *mutt_skip_whitespace (char *p)
  336. {
  337.   SKIPWS (p);
  338.   return p;
  339. }
  340.  
  341. int mutt_copy_bytes (FILE *in, FILE *out, size_t size)
  342. {
  343.   char buf[2048];
  344.   size_t chunk;
  345.  
  346.   while (size > 0)
  347.   {
  348.     chunk = (size > sizeof (buf)) ? sizeof (buf) : size;
  349.     if ((chunk = fread (buf, 1, chunk, in)) < 1)
  350.       break;
  351.     if (fwrite (buf, 1, chunk, out) != chunk)
  352.     {
  353.       dprint (1, (debugfile, "mutt_copy_bytes(): fwrite() returned short byte count\n"));
  354.       return (-1);
  355.     }
  356.     size -= chunk;
  357.   }
  358.  
  359.   return 0;
  360. }
  361.  
  362. void mutt_free_address (ADDRESS **p)
  363. {
  364.   ADDRESS *t;
  365.  
  366.   while (*p)
  367.   {
  368.     t = *p;
  369.     safe_free ((void **) &t->personal);
  370.     safe_free ((void **) &t->mailbox);
  371.     safe_free ((void **) &t->adl);
  372.     safe_free ((void **) &t->host);
  373.     *p = (*p)->next;
  374.     safe_free ((void **) &t);
  375.   }
  376. }
  377.  
  378. char *mutt_get_parameter (const char *s, PARAMETER *p)
  379. {
  380.   for (; p; p = p->next)
  381.     if (strcasecmp (s, p->attribute) == 0)
  382.       return (p->value);
  383.  
  384.   return NULL;
  385. }
  386.  
  387. /* returns 1 if Mutt can't display this type of data, 0 otherwise */
  388. int mutt_needs_mailcap (BODY *m)
  389. {
  390.   switch (m->type)
  391.   {
  392.     case TYPETEXT:
  393.  
  394.       if (!strcasecmp ("plain", m->subtype) ||
  395.       !strcasecmp ("rfc822-headers", m->subtype) ||
  396.       !strcasecmp ("enriched", m->subtype))
  397.     return 0;
  398.       break;
  399.  
  400. #ifdef _PGPPATH
  401.     case TYPEAPPLICATION:
  402.  
  403.       if (!strcasecmp ("pgp", m->subtype) ||
  404.       !strcasecmp ("pgp-signed", m->subtype) ||
  405.       !strcasecmp ("x-pgp-message", m->subtype))
  406.     return 0;
  407.       break;
  408. #endif /* _PGPPATH */
  409.  
  410.     case TYPEMULTIPART:
  411.     case TYPEMESSAGE:
  412.  
  413.       return 0;
  414.   }
  415.  
  416.   return 1;
  417. }
  418.  
  419. int mutt_is_text_type (int t, char *s)
  420. {
  421.   if (t == TYPETEXT)
  422.     return 1;
  423.  
  424.   if (t == TYPEMESSAGE)
  425.   {
  426.     if (!strcasecmp ("delivery-status", s))
  427.       return 1;
  428.   }
  429.  
  430. #ifdef _PGPPATH
  431.   if (t == TYPEAPPLICATION)
  432.   {
  433.     if (!strcasecmp ("pgp-keys", s))
  434.       return 1;
  435.